#include "net_file.h"

NetFile* net_fopen(const char* url, const char* mode) {
    if (mode[0] != 'r') {
        printf("Unsupported mode: %s\n", mode);
        return NULL; // 仅支持只读模式
    }

    NetFile* netFile = (NetFile*)malloc(sizeof(NetFile));
    if (!netFile) {
        return NULL;
    }

    netFile->hInternet = InternetOpen("NetFileAgent", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
    if (!netFile->hInternet) {
        free(netFile);
        return NULL;
    }

    netFile->hFile = InternetOpenUrl(netFile->hInternet, url, NULL, 0, INTERNET_FLAG_RELOAD, 0);
    if (!netFile->hFile) {
        InternetCloseHandle(netFile->hInternet);
        free(netFile);
        return NULL;
    }

    // 检查响应头是否包含 gzip 编码
    char encoding[64];
    DWORD encodingSize = sizeof(encoding);
    netFile->isGzip = 0;
    if (HttpQueryInfo(netFile->hFile, HTTP_QUERY_CONTENT_ENCODING, encoding, &encodingSize, NULL)) {
        if (strstr(encoding, "gzip") != NULL) {
            netFile->isGzip = 1;  // 如果是 gzip 编码，标记为 1
        }
    }

    // 获取文件大小（如果可用）
    DWORD fileSize = 0;
    DWORD fileSizeSize = sizeof(fileSize);
    if (!HttpQueryInfo(netFile->hFile, HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER, &fileSize, &fileSizeSize, NULL)) {
        fileSize = 0; // 未知文件大小
    }

    netFile->fileSize = fileSize;
    netFile->bytesRead = 0;
    netFile->bufferSize = 0;
    netFile->bufferPos = 0;
    netFile->filePos = 0;

    return netFile;
}

void net_fclose(NetFile* netFile) {
    if (netFile) {
        if (netFile->hFile) {
            InternetCloseHandle(netFile->hFile);
        }
        if (netFile->hInternet) {
            InternetCloseHandle(netFile->hInternet);
        }
        free(netFile);
    }
}

size_t net_fread(void* buffer, size_t size, size_t count, NetFile* netFile) {
    size_t bytesToRead = size * count;
    size_t totalBytesRead = 0;
    BYTE* outputBuffer = (BYTE*)buffer;

    while (bytesToRead > 0) {
        // 如果缓冲区已空，重新填充
        if (netFile->bufferPos >= netFile->bufferSize) {
            DWORD bytesRead = 0;
            if (!InternetReadFile(netFile->hFile, netFile->buffer, NETFILE_BUFFER_SIZE, &bytesRead) || bytesRead == 0) {
                break; // EOF or error
            }
            netFile->bufferSize = bytesRead;
            netFile->bufferPos = 0;
        }

        // 从缓冲区中复制数据到输出缓冲区
        DWORD bytesAvailable = netFile->bufferSize - netFile->bufferPos;
        DWORD bytesToCopy = (bytesToRead < bytesAvailable) ? bytesToRead : bytesAvailable;
        memcpy(outputBuffer + totalBytesRead, netFile->buffer + netFile->bufferPos, bytesToCopy);

        netFile->bufferPos += bytesToCopy;
        bytesToRead -= bytesToCopy;
        totalBytesRead += bytesToCopy;
        netFile->filePos += bytesToCopy;
    }

    return totalBytesRead / size;
}

int net_fseek(NetFile* netFile, long offset, int origin) {
    DWORD newPos;

    switch (origin) {
    case SEEK_SET:
        newPos = offset;
        break;
    case SEEK_CUR:
        newPos = netFile->filePos + offset;
        break;
    case SEEK_END:
        newPos = netFile->fileSize + offset;
        break;
    default:
        return -1;
    }

    if (newPos > netFile->fileSize) {
        return -1;
    }

    if (newPos != netFile->filePos) {
        if (!InternetSetFilePointer(netFile->hFile, newPos, NULL, FILE_BEGIN, 0)) {
            return -1;
        }
        netFile->filePos = newPos;
        netFile->bufferPos = netFile->bufferSize; // Force buffer reload
    }

    return 0;
}
